package com.mmall.pay.provider.config;

import com.alibaba.druid.pool.DruidDataSource;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import com.google.common.collect.Lists;
import io.seata.rm.datasource.DataSourceProxy;
import io.seata.spring.annotation.GlobalTransactionScanner;
import io.shardingsphere.core.api.MasterSlaveDataSourceFactory;
import io.shardingsphere.core.api.config.MasterSlaveRuleConfiguration;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author hejianglong
 * @date 2019/10/23
 */
@Configuration
@MapperScan(basePackages = "com.mmall.pay.provider.dao", sqlSessionFactoryRef = "mallSqlSessionFactory")
public class DBConfig {

    private final String MASTER_DATA_SOURCE = "masterDataSource";

    private final String SLAVE_1_DATA_SOURCE = "slave1DataSource";

    private final String MASTER_SLAVE = "dbMasterSlave";

    @Value("${spring.application.name}")
    private String applicationId;

    @Value("${seata.tx-service-group}")
    private String txServiceGroup;

    @Bean
    @ConfigurationProperties("spring.datasource")
    public DruidDataSource druidDataSource() {
        return new DruidDataSource();
    }

    @Bean(SLAVE_1_DATA_SOURCE)
    @ConfigurationProperties("spring.slave1.datasource")
    public DruidDataSource slave1DruidDataSource() {
        return new DruidDataSource();
    }

    @Bean(name = MASTER_DATA_SOURCE)
    public DataSource dataSource() {
        DruidDataSource druidDataSource = druidDataSource();
        return new DataSourceProxy(druidDataSource);
    }

    @Bean(MASTER_SLAVE)
    public DataSource masterSlave(@Qualifier(MASTER_DATA_SOURCE) DataSource masterDataSource, @Qualifier(SLAVE_1_DATA_SOURCE) DataSource slaveDataSource) throws SQLException {
        Map<String, DataSource> dataSourceMap = new HashMap<>();
        dataSourceMap.put(MASTER_DATA_SOURCE, masterDataSource);
        dataSourceMap.put(SLAVE_1_DATA_SOURCE, slaveDataSource);
        MasterSlaveRuleConfiguration ruleConfiguration = new MasterSlaveRuleConfiguration(MASTER_SLAVE, MASTER_DATA_SOURCE, Lists.newArrayList(SLAVE_1_DATA_SOURCE));
        return MasterSlaveDataSourceFactory.createDataSource(dataSourceMap, ruleConfiguration, new ConcurrentHashMap());
    }

    @Bean("mallSqlSessionFactory")
    public SqlSessionFactory sqlSessionFactory(@Qualifier(MASTER_SLAVE) DataSource dataSource) throws Exception {
        MybatisSqlSessionFactoryBean sqlSessionFactoryBean = new MybatisSqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(dataSource);
        sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/*.xml"));
        return sqlSessionFactoryBean.getObject();
    }

    @Bean
    public PaginationInterceptor paginationInterceptor() {
        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
        // 设置请求的页面大于最大页后操作， true调回到首页，false 继续请求  默认false
        // paginationInterceptor.setOverflow(false);
        // 设置最大单页限制数量，默认 500 条，-1 不受限制
        // paginationInterceptor.setLimit(500);
        return paginationInterceptor;
    }

    @Bean
    public GlobalTransactionScanner globalTransactionScanner() {
        return new GlobalTransactionScanner(applicationId, txServiceGroup);
    }
}
